// Copyright (c) 2012-2013, yuno. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
//    this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of contributors
//    may be used to endorse or promote products derived from this software
//    without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
package sugarmintcandy.widgetwindow;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.appwidget.AppWidgetManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Checkable;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

public class LocalePluginEditActivity extends Activity implements
	DialogInterface.OnCancelListener, DialogInterface.OnClickListener,
	AdapterView.OnItemClickListener {
    private ListView mListView;
    private Item[] mItems;

    @SuppressWarnings("deprecation")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	showDialog(R.id.locale_plugin_edit);
    }

    private static final int[] workspaceNames = { R.string.workspace_1,
	    R.string.workspace_2, R.string.workspace_3, R.string.workspace_4,
	    R.string.workspace_5, R.string.workspace_6, R.string.workspace_7,
	    R.string.workspace_8, R.string.workspace_9, R.string.workspace_10 };

    private static final int[] workspaceIcons = { R.drawable.shortcut_1,
	    R.drawable.shortcut_2, R.drawable.shortcut_3,
	    R.drawable.shortcut_4, R.drawable.shortcut_5,
	    R.drawable.shortcut_6, R.drawable.shortcut_7,
	    R.drawable.shortcut_8, R.drawable.shortcut_9,
	    R.drawable.shortcut_10 };

    @Deprecated
    @Override
    protected Dialog onCreateDialog(int id) {
	if (id == R.id.locale_plugin_edit) {
	    ArrayList<Item> items = new ArrayList<Item>();
	    for (int i = 0; i < 10; i++) {
		Item item = new Item();
		item.text = getString(workspaceNames[i]);
		item.icon = workspaceIcons[i];
		item.workspace = i + 1;
		items.add(item);
	    }
	    MainDatabase db = ((MainApplication) getApplication())
		    .getDatabase();
	    WindowInfo[] infoList = db.getWindowInfoList();
	    Collections.reverse(Arrays.asList(infoList));
	    for (WindowInfo info : infoList) {
		Item item = new Item();
		item.text = getString(R.string.show_something,
			info.getTitleBarText());
		if (info.providerInfo != null) {
		    item.packageName = info.providerInfo.provider
			    .getPackageName();
		    item.icon = info.providerInfo.icon;
		} else {
		    item.icon = android.R.drawable.ic_menu_help;
		}
		item.windowColor = info.windowColor;
		item.titleBarColor = info.titleBarColor;
		item.showAppWidgetId = info.appWidgetId;
		items.add(item);
	    }
	    for (WindowInfo info : infoList) {
		Item item = new Item();
		item.text = getString(R.string.hide_something,
			info.getTitleBarText());
		if (info.providerInfo != null) {
		    item.packageName = info.providerInfo.provider
			    .getPackageName();
		    item.icon = info.providerInfo.icon;
		} else {
		    item.icon = android.R.drawable.ic_menu_help;
		}
		item.overlay = R.drawable.shortcut_close_overlay;
		item.windowColor = info.windowColor;
		item.titleBarColor = info.titleBarColor;
		item.hideAppWidgetId = info.appWidgetId;
		items.add(item);
	    }
	    mItems = items.toArray(new Item[items.size()]);
	    MyAdapter adapter = new MyAdapter(mItems);
	    mListView = new ListView(this);
	    mListView.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE);
	    mListView.setOnItemClickListener(this);
	    mListView.setAdapter(adapter);
	    Intent intent = getIntent();
	    if (intent != null) {
		Bundle bundle = intent
			.getBundleExtra(Constants.EXTRA_LOCALE_BUNDLE);
		if (bundle != null) {
		    int workspace = bundle.getInt(Constants.LOCALE_WORKSPACE,
			    -1);
		    HashSet<Integer> showIds = new HashSet<Integer>();
		    String showIdsString = bundle
			    .getString(Constants.LOCALE_SHOW_APPWIDGETIDS);
		    if (showIdsString != null) {
			for (String s : showIdsString.split(" ")) {
			    try {
				showIds.add(Integer.parseInt(s));
			    } catch (NumberFormatException ex) {
				Debug.warn(ex);
			    }
			}
		    }
		    HashSet<Integer> hideIds = new HashSet<Integer>();
		    String hideIdsString = bundle
			    .getString(Constants.LOCALE_HIDE_APPWIDGETIDS);
		    if (hideIdsString != null) {
			for (String s : hideIdsString.split(" ")) {
			    try {
				hideIds.add(Integer.parseInt(s));
			    } catch (NumberFormatException ex) {
				Debug.warn(ex);
			    }
			}
		    }
		    for (int i = 0, n = mItems.length; i < n; i++) {
			Item item = mItems[i];
			if (item.workspace == workspace
				|| showIds.contains(item.showAppWidgetId)
				|| hideIds.contains(item.hideAppWidgetId)) {
			    mListView.setItemChecked(i, true);
			}
		    }
		}
	    }
	    AlertDialog.Builder d = new AlertDialog.Builder(this);
	    d.setTitle(R.string.app_name);
	    d.setCancelable(true);
	    d.setOnCancelListener(this);
	    d.setView(mListView);
	    d.setPositiveButton(android.R.string.ok, this);
	    d.setNegativeButton(android.R.string.cancel, this);
	    return d.create();
	}
	return super.onCreateDialog(id);
    }

    @Override
    public void onCancel(DialogInterface dialog) {
	setResult(RESULT_CANCELED);
	finish();
    }

    @Override
    public void onClick(DialogInterface dialog, int which) {
	if (which == DialogInterface.BUTTON_POSITIVE) {
	    setResult(RESULT_OK, createResult());
	    finish();
	}
	if (which == DialogInterface.BUTTON_NEGATIVE) {
	    setResult(RESULT_CANCELED);
	    finish();
	}
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position,
	    long id) {
	if (!mListView.isItemChecked(position)) {
	    return;
	}
	Item item = mItems[position];
	int workspace = item.workspace;
	int showAppWidgetId = item.showAppWidgetId;
	int hideAppWidgetId = item.hideAppWidgetId;
	if (workspace > 0) {
	    for (int i = 0, n = mItems.length; i < n; i++) {
		if (mItems[i].workspace > 0 && mItems[i].workspace != workspace) {
		    mListView.setItemChecked(i, false);
		}
	    }
	}
	if (showAppWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
	    for (int i = 0, n = mItems.length; i < n; i++) {
		if (showAppWidgetId == mItems[i].hideAppWidgetId) {
		    mListView.setItemChecked(i, false);
		}
	    }
	}
	if (hideAppWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
	    for (int i = 0, n = mItems.length; i < n; i++) {
		if (hideAppWidgetId == mItems[i].showAppWidgetId) {
		    mListView.setItemChecked(i, false);
		}
	    }
	}
    }

    private Intent createResult() {
	Bundle bundle = new Bundle();
	HashSet<Integer> showIds = new HashSet<Integer>();
	HashSet<Integer> hideIds = new HashSet<Integer>();
	ArrayList<String> blurb = new ArrayList<String>();
	for (int i = 0, n = mItems.length; i < n; i++) {
	    if (mListView.isItemChecked(i)) {
		Item item = mItems[i];
		blurb.add(item.text);
		if (item.workspace >= 1) {
		    bundle.putInt(Constants.LOCALE_WORKSPACE, item.workspace);
		}
		if (item.showAppWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
		    showIds.add(item.showAppWidgetId);
		}
		if (item.hideAppWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) {
		    hideIds.add(item.hideAppWidgetId);
		}
	    }
	}
	if (!showIds.isEmpty()) {
	    bundle.putString(Constants.LOCALE_SHOW_APPWIDGETIDS,
		    join(" ", showIds));
	}
	if (!hideIds.isEmpty()) {
	    bundle.putString(Constants.LOCALE_HIDE_APPWIDGETIDS,
		    join(" ", hideIds));
	}
	Intent result = new Intent();
	result.putExtra(Constants.EXTRA_LOCALE_BLURB, join(", ", blurb));
	result.putExtra(Constants.EXTRA_LOCALE_BUNDLE, bundle);
	return result;
    }

    private String join(String sep, Collection<?> c) {
	Iterator<?> i = c.iterator();
	if (!i.hasNext()) {
	    return null;
	}
	String s = String.valueOf(i.next());
	if (!i.hasNext()) {
	    return s;
	}
	StringBuilder sb = new StringBuilder(s);
	while (i.hasNext()) {
	    sb.append(sep).append(i.next());
	}
	return sb.toString();
    }

    private Bitmap createIconBitmap(Item item) {
	try {
	    int iconSize = getResources().getDimensionPixelSize(
		    R.dimen.icon_size);
	    Bitmap bitmap = Bitmap.createBitmap(iconSize, iconSize,
		    Bitmap.Config.ARGB_8888);
	    Canvas canvas = new Canvas(bitmap);
	    canvas.drawARGB(0, 0, 0, 0);
	    int p1 = 0;
	    int p2 = iconSize / 12;
	    int p3 = iconSize;
	    if (item.titleBarColor != 0) {
		Paint paint = new Paint();
		paint.setColor(item.titleBarColor);
		paint.setStyle(Paint.Style.FILL);
		canvas.drawRect(p1, p1, p3, p2, paint);
	    }
	    if (item.windowColor != 0) {
		Paint paint = new Paint();
		paint.setColor(item.windowColor);
		paint.setStyle(Paint.Style.FILL);
		canvas.drawRect(p1, p2, p3, p3, paint);
	    }
	    if (item.icon != 0) {
		Context context = this;
		if (item.packageName != null) {
		    context = createPackageContext(item.packageName, 0);
		}
		Bitmap icon = BitmapFactory.decodeResource(
			context.getResources(), item.icon);
		if (icon != null) {
		    int sw = icon.getWidth();
		    int sh = icon.getHeight();
		    float dw = p3 - p1;
		    float dh = p3 - p2;
		    if (dw * sh < dh * sw) {
			dh = dw * sh / sw;
		    } else {
			dw = dh * sw / sh;
		    }
		    float dx = (p1 + p3 - dw) / 2;
		    float dy = (p2 + p3 - dh) / 2;
		    Paint paint = new Paint();
		    paint.setFilterBitmap(true);
		    canvas.drawBitmap(icon, new Rect(0, 0, sw, sh), new RectF(
			    dx, dy, dx + dw, dy + dh), paint);
		}
	    }
	    if (item.overlay != 0) {
		Bitmap icon = BitmapFactory.decodeResource(getResources(),
			R.drawable.shortcut_close_overlay);
		if (icon != null) {
		    int w = icon.getWidth();
		    int h = icon.getHeight();
		    int dx = p3 - w;
		    int dy = p1;
		    canvas.drawBitmap(icon, new Rect(0, 0, w, h), new Rect(dx,
			    dy, dx + w, dy + h), new Paint());
		}
	    }
	    return bitmap;
	} catch (Throwable ex) {
	    Debug.warn(ex);
	    return null;
	}
    }

    private static class Item {
	String text;
	String packageName;
	int icon;
	int overlay;
	int windowColor;
	int titleBarColor;
	int workspace;
	int showAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
	int hideAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
    }

    private class MyAdapter extends BaseAdapter {
	private Item[] mItems;

	MyAdapter(Item[] items) {
	    mItems = items;
	}

	@Override
	public int getCount() {
	    return mItems.length;
	}

	@Override
	public Item getItem(int position) {
	    return mItems[position];
	}

	@Override
	public long getItemId(int position) {
	    return position;
	}

	@Override
	public View getView(int position, View view, ViewGroup parent) {
	    Context context = parent.getContext();
	    MyItemView v;
	    if (view instanceof MyItemView) {
		v = (MyItemView) view;
	    } else {
		v = new MyItemView(context);
	    }
	    Item item = getItem(position);
	    v.mTextView.setText(item.text);
	    v.mImageView.setImageBitmap(createIconBitmap(item));
	    return v;
	}
    }

    private class MyItemView extends FrameLayout implements Checkable {
	boolean mChecked;
	ImageView mImageView;
	TextView mTextView;

	MyItemView(Context context) {
	    super(context);
	    LayoutInflater.from(context).inflate(
		    R.layout.locale_plugin_edit_item, this);
	    mImageView = (ImageView) findViewById(R.id.image_view);
	    mTextView = (TextView) findViewById(android.R.id.text1);
	}

	@Override
	public boolean isChecked() {
	    return mChecked;
	}

	@Override
	public void setChecked(boolean checked) {
	    mChecked = checked;
	    drawableStateChanged();
	}

	@Override
	public void toggle() {
	    setChecked(!isChecked());
	}

	@Override
	protected int[] onCreateDrawableState(int extraSpace) {
	    if (isChecked()) {
		int[] state = super.onCreateDrawableState(extraSpace + 1);
		mergeDrawableStates(state,
			new int[] { android.R.attr.state_checked });
		return state;
	    } else {
		return super.onCreateDrawableState(extraSpace);
	    }
	}
    }
}
